let that

class MeasureTool {
    constructor(map) {
        that = this
        that.map = map
        that.mapDom = map.getCanvasContainer()
        that.coords = []

        that.map.addSource('measure-result-length', {
            "type": "geojson",
            "data": that.getGeojson([])
        })
        that.map.addSource('measure-result-area', {
            "type": "geojson",
            "data": that.getGeojson([])
        })
        that.map.addLayer({
            id: 'measure-result-length',
            source: 'measure-result-length',
            type: 'line',
            "paint": {
                "line-width": 3,
                "line-color": "red"
            }
        })

        that.map.addLayer({
            id: 'measure-result-area-line',
            source: 'measure-result-area',
            type: 'line',
            "paint": {
                "line-width": 3,
                "line-color": "red"
            }
        })
        that.map.addLayer({
            id: 'measure-result-area-fill',
            source: 'measure-result-area',
            type: 'fill',
            "paint": {
                "fill-opacity": 0.3,
                "fill-color": "red"
            }
        })

        // 鼠标提示展示 , .setLngLat(coords)
        that.domTips = document.createElement('div')
        that.domTips.classList.add('tool-tips')
        that.toolTips = new mapboxgl.Marker({
            element: that.domTips,
            anchor: 'left',
            offset: [1.6, 0]
        }).setLngLat([-180, -90]).addTo(that.map);

    }

    clickEvent(e) {
        if(!that.type) return
        const {lng, lat} = e.lngLat
        that.coords.push([lng, lat])
    }

    dblclickEvent(e) {
        if(!that.type) return
        const coords = that.coords.concat([])
        if(that.type === 'length') {
            if(coords.length > 1) {
                // 显示距离
                const lineString = turf.lineString(coords)
                const len = turf.length(lineString)
                that.domTips.innerText = that.formatLength(len)
                that.map.getSource('measure-result-length').setData(lineString)
                const coord = coords[coords.length - 1]
                that.toolTips.setLngLat(coord)
            }
        } else {
            if(coords.length > 2) {
                // 显示面积
                coords.push(coords[0])
                const polygon = turf.polygon([coords])
                const area = turf.area(polygon)
                that.domTips.innerText = that.formatArea(area)
                that.map.getSource('measure-result-area').setData(polygon)
                const coord = coords[coords.length - 2]
                that.toolTips.setLngLat(coord)
            }
        }
        that.stopMeasure()
    }

    mousemoveEvent(e) {
        if(!that.type) return
        const {lng, lat} = e.lngLat
        if(that.coords.length === 0) {
            if(that.type === 'length') {
                that.domTips.innerText = '点击地图开始测量距离'
            } else {
                that.domTips.innerText = '点击地图开始测量面积'
            }
        } else {
            const coords = that.coords.concat([])
            coords.push([lng, lat])
            if(that.type === 'length') {
                if(coords.length > 1) {
                    // 显示距离
                    const lineString = turf.lineString(coords)
                    const len = turf.length(lineString)
                    that.domTips.innerText = that.formatLength(len)
                    that.map.getSource('measure-result-length').setData(lineString)
                }
            } else {
                if(coords.length > 2) {
                    // 显示面积
                    coords.push(coords[0])
                    const polygon = turf.polygon([coords])
                    const area = turf.area(polygon)
                    that.domTips.innerText = that.formatArea(area)
                    that.map.getSource('measure-result-area').setData(polygon)
                } else {
                    const lineString = turf.lineString(coords)
                    that.map.getSource('measure-result-area').setData(lineString)
                    that.domTips.innerText = '继续点击地图开始测量面积'
                }
            }
        }
        that.toolTips.setLngLat([lng, lat])
    }

    formatLength(len) {
        return len > 1 ? len.toFixed(2) + 'km' : (len * 1000).toFixed(0) + 'm'
    }

    formatArea(area) {
        return area > 1 ? area.toFixed(2) + 'km²' : (area * 1000).toFixed(0) + 'm²'
    }

    /**
     * 激活测量
     * @param type - 测量类型length, area
     */
    activeMeasure(type) {
        that.coords = []
        that.type  =  type
        that.map.getSource('measure-result-length').setData(that.getGeojson([]))
        that.map.getSource('measure-result-area').setData(that.getGeojson([]))
        that.mapDom.style.cursor = 'crosshair'
        map.on('click', that.clickEvent)
        map.on('dblclick', that.dblclickEvent)
        map.on('mousemove', that.mousemoveEvent)
    }

    /**
     *
     */
    deactiveMeasure() {
        that.stopMeasure()
        that.toolTips.setLngLat([-180, -90])
        that.map.getSource('measure-result-length').setData(that.getGeojson([]))
        that.map.getSource('measure-result-area').setData(that.getGeojson([]))
    }

    stopMeasure() {
        that.coords = []
        that.type  =  ''
        that.mapDom.style.cursor = ''
        map.off('click', that.clickEvent)
        map.off('dblclick', that.dblclickEvent)
        map.off('mousemove', that.mousemoveEvent)
    }

    getGeojson(features) {
        return {
            "type": "FeatureCollection",
            features: features
        }
    }
}